use crate::{
    models::{
        date_range::DateRange,
        statement::{EntryItem, ResignationItem},
    },
    reply::Reply,
    state::State,
};
use entity::{
    department, personnel, position,
    prelude::{Department, Personnel, Position, Resignation},
    resignation,
};
use poem::{
    handler,
    web::{Data, Query},
};
use sea_orm::{prelude::Date, ColumnTrait, EntityTrait, QueryFilter, QueryOrder, QuerySelect};

#[handler]
pub async fn entry(
    Data(State { db, .. }): Data<&State>,
    Query(DateRange { start, end }): Query<DateRange<Date, Date>>,
) -> Reply<Vec<EntryItem>> {
    let items = Personnel::find()
        .inner_join(Department)
        .inner_join(Position)
        .filter(personnel::Column::EntryDate.between(start, end))
        .filter(personnel::Column::IsEmployed.eq(true))
        .order_by_asc(personnel::Column::EntryDate)
        .select_only()
        .column(personnel::Column::Name)
        .column(personnel::Column::Sex)
        .column(personnel::Column::EntryDate)
        .column(personnel::Column::Education)
        .column_as(department::Column::Name, "department")
        .column_as(position::Column::Name, "position")
        .into_model::<EntryItem>()
        .all(db)
        .await
        .unwrap();

    Reply::new().data(items)
}

#[handler]
pub async fn resign(
    Data(State { db, .. }): Data<&State>,
    Query(DateRange { start, end }): Query<DateRange<Date, Date>>,
) -> Reply<Vec<ResignationItem>> {
    let items = Personnel::find()
        .left_join(Resignation)
        .inner_join(Department)
        .inner_join(Position)
        .filter(personnel::Column::EntryDate.between(start, end))
        .filter(personnel::Column::IsEmployed.eq(false))
        .order_by_asc(resignation::Column::ResignDate)
        .select_only()
        .column(personnel::Column::Name)
        .column(personnel::Column::Sex)
        .column(resignation::Column::ResignDate)
        .column_as(resignation::Column::Remark, "reason")
        .column_as(department::Column::Name, "department")
        .column_as(position::Column::Name, "position")
        .into_model::<ResignationItem>()
        .all(db)
        .await
        .unwrap();

    Reply::new().data(items)
}
